package la.iok.hzsvn.lewin.movie.operation.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import la.iok.hzsvn.lewin.movie.core.RoleEnum;
import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.core.model.*;
import la.iok.hzsvn.lewin.movie.operation.cfg.PlayRecordAutoEndProperties;
import la.iok.hzsvn.lewin.movie.operation.entity.FinancialAccount;
import la.iok.hzsvn.lewin.movie.operation.entity.LuckyMoney;
import la.iok.hzsvn.lewin.movie.operation.entity.PlayRecord;
import la.iok.hzsvn.lewin.movie.operation.entity.SupportReturnMoneyShop;
import la.iok.hzsvn.lewin.movie.operation.mapper.PlayRecordMapper;
import la.iok.hzsvn.lewin.movie.operation.model.*;
import la.iok.hzsvn.lewin.movie.services.MovieServiceInvoker;
import la.iok.hzsvn.lewin.mybatis.model.PageVo;
import la.iok.hzsvn.lewin.mybatis.service.BaseServiceImpl;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.NotNullElement;
import la.iok.hzsvn.share.annotations.Nullable;
import la.iok.hzsvn.share.collection.IdOperators;
import la.iok.hzsvn.share.tools.datetime.DateTimeUtil;
import la.iok.hzsvn.share.utils.CollectionUtils;
import la.iok.hzsvn.share.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static la.iok.hzsvn.lewin.movie.core.exception.ErrorCode.*;

@Service
public class PlayRecordServiceImpl extends BaseServiceImpl<PlayRecord, PlayRecordMapper, Long> implements PlayRecordService{
    private static final Logger logger = LoggerFactory.getLogger(PlayRecordService.class);
    private final FinancialAccountService financialAccountService;
    private final MovieServiceInvoker movieServiceInvoker;
    private final LuckyMoneyService luckyMoneyService;
    private final FeeRecordService feeRecordService;
    private final SupportReturnMoneyShopService supportReturnMoneyShopService;
    private final PlayRecordAutoEndProperties playRecordAutoEndProperties;
    /**
     * 信用基数。开本的时候，如果减去开本金额剩余金额少于此基数，则不能开本。当前为-100元
     */
    private static final int credit_base = -10000;

    public PlayRecordServiceImpl(PlayRecordMapper mapper,
                                 FinancialAccountService financialAccountService,
                                 MovieServiceInvoker movieServiceInvoker,
                                 LuckyMoneyService luckyMoneyService,
                                 FeeRecordService feeRecordService,
                                 SupportReturnMoneyShopService supportReturnMoneyShopService,
                                 PlayRecordAutoEndProperties playRecordAutoEndProperties) {
        super(mapper);
        this.financialAccountService = financialAccountService;
        this.movieServiceInvoker = movieServiceInvoker;
        this.luckyMoneyService = luckyMoneyService;
        this.feeRecordService = feeRecordService;
        this.supportReturnMoneyShopService = supportReturnMoneyShopService;
        this.playRecordAutoEndProperties = playRecordAutoEndProperties;
    }

    @Transactional
    @Override
    public Long start(@NotNull Token token, @NotNull PlayRecordParam param) {
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(token.getDeviceId(),"设备","只能使用设备的令牌访问");
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(param.getDmId(),"DM","DM的id不能为空");
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(param.getMovieId(),"剧本","剧本id不能为空");
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotBlank(param.getVersion(),"剧本","剧本版本不能为空");
        DeviceVo device = movieServiceInvoker.deviceInfo(token.getDeviceId());
        ErrorCode.DEVICE_NOT_EXIST.assertNotNull(device,token.getDeviceId());
        ErrorCode.DEVICE_NOT_BELONG_ORG_UNIT.assertNotNull(device.getOrgUnitId(),token.getDeviceId(),"任何组织");
        ErrorCode.DEVICE_NOT_BELONG_ORG_UNIT.assertNotBlank(device.getOrgUnitName(),token.getDeviceId(),"任何组织");
        PROPERTY_CHECK_ERROR.assertTrue(device.getRoomId() != null && device.getRoomId() > 0,"房间","设备未关联房间");
        SimpleOrgUnitVo orgUnit = movieServiceInvoker.orgUnitInfo(device.getOrgUnitId());
        ORG_UNIT_NOT_EXIST.assertNotNull(orgUnit,device.getOrgUnitId());
        ORG_UNIT_NOT_EXIST.assertTrue(orgUnit.normalStatus(),device.getOrgUnitId());
        UserVo user = movieServiceInvoker.userInfo(param.getDmId());
        ErrorCode.INVALID_USER.assertNotNull(user);
        ErrorCode.AUTHORITY_ERROR.assertTrue(user.hasRole(RoleEnum.DM),RoleEnum.DM.getDisplayName());
        ErrorCode.ORG_UNIT_ACCESS_DENIED.assertEqual(device.getOrgUnitId(),user.getOrgUnitId(),device.getOrgUnitName());
        MovieVo movie = movieServiceInvoker.movieInfo(param.getMovieId(),param.getVersion());
        ErrorCode.MOVIE_NOT_EXIST.assertNotNull(movie,()->new Object[]{String.format("%s-%s",param.getMovieId(),param.getVersion())});
        ErrorCode.MOVIE_NOT_EXIST.assertNotBlank(movie.getName(),()->new Object[]{String.format("%s-%s",param.getMovieId(),param.getVersion())});
        int cost = movie.getPrice() == null || (param.getTest() != null && param.getTest() == 1)?0:movie.getPrice();
        FinancialAccount account = financialAccountService.account(device.getRoomId());
        PROPERTY_CHECK_ERROR.assertNotNull(account,"账号","余额账号不存在");
        int balance = account.getBalance() == null?0:account.getBalance();
        LuckyMoney luckyMoney = luckyMoneyService.currentReturnMoney(device.getRoomId());
        int luckyAmount = luckyMoney==null?0:luckyMoney.getAmount();
        int remain = balance + luckyAmount - cost;
        ErrorCode.FINANCIAL_ACCOUNT_BALANCE_INSUFFICIENT.assertTrue(remain > credit_base,()->new Object[]{
                String.format("%.2f元",(float)balance / 100),String.format("%.2f元",(float)cost / 100)
        });
        int luckyMoneyCost = 0;
        int payAmount = 0;
        if(cost > 0){
            luckyMoneyCost = luckyMoneyService.use(luckyMoney,cost);
            payAmount = cost - luckyMoneyCost;
            if(payAmount > 0){
                int cnt = financialAccountService.cost(device.getRoomId(),payAmount,account.getVersion());
                ErrorCode.FINANCIAL_ACCOUNT_COST_ERROR.assertEqual(1,cnt);
            }
        }
        account = financialAccountService.account(device.getRoomId());
        PlayRecord entity = new PlayRecord();
        entity.setDeviceId(device.getId());
        entity.setDeviceName(device.getName());
        entity.setDmAccount(user.getPhoneNumber());
        entity.setDmId(user.getId());
        entity.setMovieName(movie.getName());
        entity.setMovieId(movie.getId());
        entity.setMovieVersion(movie.getVersion());
        entity.setOrgUnitId(device.getOrgUnitId());
        entity.setOrgUnitName(device.getOrgUnitName());
        entity.setRoomId(device.getRoomId());
        entity.setRoomName(device.getRoomName());
        entity.setStatus(PlayRecordVo.STATUS_IN_PROGRESS);
        entity.setStartTime(new Date());
        entity.setCost(cost);
        entity.setPayAmount(payAmount);
        entity.setLuckyAmount(luckyMoneyCost);
        entity.setTest(param.getTest());
        entity.setAccountRemained(account.getBalance());
        insertSelective(entity);
        movieServiceInvoker.increasePlayTimes(param.getMovieId(),param.getVersion());
        if(luckyMoneyCost > 0){
            feeRecordService.save(luckyMoney.getId(),entity.getId(),luckyMoneyCost);
        }
        return entity.getId();
    }

    @Override
    public void end(@NotNull Token token, @Nullable EndParam param) {
        INVALID_OPERATION.assertNotNull(param);
        PlayRecord pr = select(param.getId());
        ErrorCode.RECORD_NOT_EXIST.assertNotNull(pr,param.getId());
        ErrorCode.PLAY_RECORD_ENDING.assertFalse(pr.ending(),param.getId());
        ErrorCode.PLAY_RECORD_ENDED.assertTrue(pr.playing(),param.getId());
        if(token.getDeviceId() != null){
            //验证是当前设备关联的播放记录
            PLAY_RECORD_ACCESS_DENIED.assertEqual(pr.getDeviceId(),token.getDeviceId(),param.getId());
            PROPERTY_CHECK_ERROR.assertNotNull(param.getUserId(),"用户","操作用户id不能为空");
            pr.setTerminatorId(param.getUserId());
            pr.setEndType(PlayRecordVo.END_TYPE_DEVICE);
        } else {
            //用户：超级管理员、管理员和DM都有不同的权限
            if(token.hasAuthority(RoleEnum.Admin)){
                //ok
            }else if(token.hasAuthority(RoleEnum.Manager)){
                //管理员
                if(!Objects.equals(token.getOrgUnitId(),pr.getOrgUnitId())){
                    List<Long> list = movieServiceInvoker.childrenOrgUnitIds(token.getOrgUnitId());
                    PLAY_RECORD_ACCESS_DENIED.assertNotEmpty(list,param.getId());
                    PLAY_RECORD_ACCESS_DENIED.assertTrue(list.contains(pr.getOrgUnitId()),param.getId());
                }
            }else if(token.hasAuthority(RoleEnum.DM)){
                //只能终止自己店铺内的开本记录
                PLAY_RECORD_ACCESS_DENIED.assertEqual(pr.getOrgUnitId(),token.getOrgUnitId(),param.getId());
            }
            pr.setTerminatorId(token.getUserId());
            pr.setEndType(PlayRecordVo.END_TYPE_USER);
        }
        pr.setEndTime(new Date());
        ErrorCode.PLAY_RECORD_END_FAILED.assertEqual(1,mapper.end(pr),param.getId());
    }

    @Override
    public int endBySystem() {
        Integer more = playRecordAutoEndProperties.getMoreHours();
        return mapper.endBySystem(more==null || more <= 0?2:more);
    }

    @NotNull
    @NotNullElement
    @Override
    public List<PlayRecord> playingRecords(@NotNull Token token) {
        if(token.getDeviceId() != null){
            //设备的
            return mapper.devicePlayingRecord(token.getDeviceId());
        }else{
            return mapper.userPlayingRecord(token.getUserId(),token.getOrgUnitId());
        }
    }

    @Override
    public List<PlayRecord> need2End() {
        return mapper.need2End(playRecordAutoEndProperties.getMoreHours());
    }

    @NotNull
    @NotNullElement
    @Override
    public List<PlayRecord> roomPlayingRecords(@Nullable Long roomId) {
        if(roomId == null){
            return Collections.emptyList();
        }
        return mapper.roomPlayingRecord(roomId);
    }

    @NotNull
    @NotNullElement
    @Override
    public List<PlayRecordVo> po2vo(@Nullable @NotNullElement List<PlayRecord> playRecords) {
        if(playRecords == null || playRecords.isEmpty()){
            return Collections.emptyList();
        }
        Set<Long> dms = playRecords.stream().map(PlayRecord::getDmId).filter(Objects::nonNull).collect(Collectors.toSet());
        Set<Long> terninators = playRecords.stream().map(PlayRecord::getTerminatorId).filter(Objects::nonNull).collect(Collectors.toSet());
        Set<Long> userIds = new HashSet<>(dms);
        userIds.addAll(terninators);
        List<SimpleUser> list = movieServiceInvoker.userInfo(userIds);
        return playRecords.stream().map(item->{
            PlayRecordVo vo = new PlayRecordVo();
            BeanUtils.copyProperties(item,vo);
            SimpleUser u = IdOperators.find(list,item.getDmId());
            if(u!=null){
                vo.setDmAccount(u.getPhoneNumber());
                vo.setDmNickname(u.getNickname());
            }
            u = IdOperators.find(list,item.getTerminatorId());
            if(u!=null){
                vo.setTerminator(StringUtils.defaultIfBlank(u.getNickname(),u.getPhoneNumber()));
            }else if(PlayRecord.TERMINATOR_ID_SYSTEM.equals(item.getTerminatorId())){
                vo.setTerminator(PlayRecord.TERMINATOR_SYSTEM);
            }
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public PlayRecordVo po2vo(PlayRecord playRecord) {
        if(playRecord == null){
            return null;
        }
        PlayRecordVo vo = new PlayRecordVo();
        BeanUtils.copyProperties(playRecord,vo);
        return vo;
    }

    @Override
    public PageVo<PlayRecordVo> page(Token token, int page, int limit, String orderColumn, String order,
                                     Long orgUnitId, Long userId) {
        return page(token,page,limit,orderColumn,order,null,orgUnitId,null,userId,null,null);
    }

    @Override
    public PageVo<PlayRecordVo> page(Token token, int page, int limit, String orderColumn, String order, String name,
                                     Long orgUnitId, Long roomId, Long userId, Date start, Date end) {
        orderColumn = StringUtils.isBlank(orderColumn)?"status":orderColumn;
        order = StringUtils.isBlank(order)?"ascending":order;
        order = "ascending".equalsIgnoreCase(order)?"ASC":"DESC";
        List<Long> orgUnits = null;
        Long playerId = null;
        boolean removePhone = false;
        if(token.hasAuthority(RoleEnum.Admin)){
            //nothing
        }else{
            playerId = token.getUserId();
            orgUnits = movieServiceInvoker.childrenOrgUnitIds(token.getOrgUnitId());
            orgUnits = orgUnits == null?new ArrayList<>():new ArrayList<>(orgUnits);
            if(token.getOrgUnitId() != null){
                orgUnits.add(token.getOrgUnitId());
            }
            if(CollectionUtils.isEmpty(orgUnits) && playerId == null){
                return new PageVo<>(limit,page);
            }
            if(!token.hasAuthority(RoleEnum.Manager)){
                removePhone = true;
                if(token.hasAuthority(RoleEnum.ShopManager)){
                    //不是管理员,但是有店长权限，店长能看到的记录最早只能到自己成为店长的那个时间
                    List<UserRoleDetail> details = movieServiceInvoker.userRoles(token.getUserId());
                    UserRoleDetail ur = details.stream().filter(detail->Objects.equals(detail.getOrgUnitId(),token.getOrgUnitId())
                            && Objects.equals(detail.getRole(),RoleEnum.ShopManager.name())).findFirst().orElse(null);
                    if (ur != null && ur.getAddTime() != null){
                        if(start == null){
                            start = ur.getAddTime();
                        }else{
                            if(ur.getAddTime().after(start)){
                                start = ur.getAddTime();
                            }
                        }
                    }
                }
            }
        }

        Page<PlayRecord> list = PageHelper.startPage(page,limit);
        mapper.list(orderColumn,order,playerId,orgUnits,orgUnitId,userId,name,roomId,start,end);
        List<PlayRecordVo> data = po2vo(list);
        if(removePhone){
            data.forEach(vo->vo.setDmAccount(null));
        }
        PageVo<PlayRecordVo> pageVo = new PageVo<>();
        pageVo.setPages(list.getPages());
        pageVo.setTotal(list.getTotal());
        pageVo.setCurrent(list.getPageNum());
        pageVo.setSize(list.getPageSize());
        pageVo.setRecords(data);
        return pageVo;
    }

    @NotNull
    @Override
    public PlayRecordVo enter(@NotNull Token token, @Nullable Long id) {
        PlayRecord pr = select(id);
        ErrorCode.RECORD_NOT_EXIST.assertNotNull(pr,id);
        ErrorCode.PLAY_RECORD_ENDED.assertTrue(pr.playing(),id);
        PLAY_RECORD_ACCESS_DENIED.assertEqual(pr.getDeviceId(),token.getDeviceId(),id);
        return po2vo(pr);
    }

    @Override
    public int total(@NotNull Token token, @NotNull Date start, @NotNull Date end) {
        Integer total;
        if(token.hasAuthority(RoleEnum.Admin)){
            total = mapper.total(start,end,null);
        }else{
            List<Long> list = movieServiceInvoker.childrenOrgUnitIds(token.getOrgUnitId());
            if(list.isEmpty()){
                total = mapper.total(start,end,Collections.singletonList(token.getOrgUnitId()));
            }else{
                total = mapper.total(start,end,list);
            }
        }
        return total != null?total:0;
    }

    @Override
    public int totalPlays(@NotNull Date start, @NotNull Date end,@Nullable Long roomId, @Nullable @NotNullElement Collection<Long> excludeMovieIds) {
        if(roomId == null){
            return 0;
        }
        return mapper.countPlays(start,end,roomId, excludeMovieIds);
    }

    @Override
    public int totalCost(@NotNull Date start, @NotNull Date end,@Nullable Long roomId, @Nullable @NotNullElement Collection<Long> excludeMovieIds) {
        if(roomId == null){
            return 0;
        }
        Integer sum = mapper.totalCost(start,end,roomId,excludeMovieIds);
        return sum==null?0:sum;
    }

    @Nullable
    @Override
    public FinancialAccount processReturnMoney(@NotNull @NotNullElement Collection<Long> excludes, @NotNull @NotNullElement Collection<Long> success,
                                               @NotNull @NotNullElement Collection<Long> lessAmount, @NotNull Date start, @NotNull Date end,
                                               @Nullable @NotNullElement Collection<Long> excludeMovieIds, @NotNull @NotNullElement Collection<Long> supportReturnMoneyRoomIds) {
        FinancialAccount account = financialAccountService.takeOneForReturn(excludes, supportReturnMoneyRoomIds);
        if(account == null){
            return null;
        }
        try{
            int plays = totalPlays(start, end, account.getRoomId(),excludeMovieIds);
            if(plays >= 30){
                int cost = totalCost(start, end,account.getRoomId(),excludeMovieIds);
                cost /= 2;
                LuckyMoney r = luckyMoneyService.currentReturnMoney(account.getRoomId());
                if(r != null){
                    if(!Objects.equals(r.getInitAmount(),cost)){
                        // 这种情况记录日志
                        logger.warn("账号[id:{}]已经存在返利记录[id:{},初始金额:{}],与当前计算返利金额[{}]不同",account.getId(),r.getId(),r.getInitAmount(),cost);
                        excludes.add(account.getId()); //下次计算排除这条记录
                        financialAccountService.returnMonthBack(account);
                    }
                }else{
                    Long id = luckyMoneyService.saveReturnMoney(account.getRoomId(), cost);
                    if(id != null){
                        success.add(account.getId());
                    }
                }
            }else{
                lessAmount.add(account.getId());
            }
        }catch (Exception e){
            logger.error("处理账号[id:{}]异常", account.getId(),e);
            excludes.add(account.getId());
            financialAccountService.returnMonthBack(account);
        }
        return account;
    }

    @Override
    public void processReturnMoney(Collection<Long> excludes, Collection<Long> success, Collection<Long> lessAmount) {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.DAY_OF_MONTH,1);
        now.add(Calendar.MONTH,-1);
        Date start = DateTimeUtil.setTime(DateTimeUtil.monthStart(now.getTime()),0,0,0,0);
        Date end = DateTimeUtil.setTime(DateTimeUtil.monthEnd(now.getTime()),23,59,59,999);
        List<Long> unsupportedMovieIds = movieServiceInvoker.unsupportedReturnMoneyMovieIds();
        Set<Long> supportReturnMoneyShops = supportReturnMoneyShopService.selectAll().stream().map(SupportReturnMoneyShop::getOrgUnitId).collect(Collectors.toSet());
        Set<Long> roomIds = movieServiceInvoker.shopRooms(supportReturnMoneyShops).stream().map(RoomVo::getId).collect(Collectors.toSet());
        do{
            RETURN_MONEY_ROOM_EMPTY.assertNotEmpty(roomIds);
            try{
                FinancialAccount account = processReturnMoney(excludes, success, lessAmount, start, end, unsupportedMovieIds,roomIds);
                if (account == null) break;
            }catch (Exception e){
                logger.error("处理账号返利失败",e);
            }
        }while (true);
    }

    @NotNull
    @Override
    public PreviewLuckyMoney previewReturnMoney(@NotNull Token token) {
        token.validAnyAuthority(RoleEnum.Admin);
        PreviewLuckyMoney previewLuckyMoney = new PreviewLuckyMoney();
        Calendar now = Calendar.getInstance();
        Date start = DateTimeUtil.setTime(DateTimeUtil.monthStart(now.getTime()),0,0,0,0);
        Date end = DateTimeUtil.setTime(DateTimeUtil.monthEnd(now.getTime()),23,59,59,999);
        now.set(Calendar.DAY_OF_MONTH,1);
        now.add(Calendar.MONTH,1);  //下个月内有效
        Date begin = DateTimeUtil.setTime(DateTimeUtil.monthStart(now.getTime()),0,0,0,0);
        Date invalid = DateTimeUtil.setTime(DateTimeUtil.monthEnd(now.getTime()),23,59,59,999);
        List<Long> unsupportedMovieIds = movieServiceInvoker.unsupportedReturnMoneyMovieIds();
        Set<Long> supportReturnMoneyShops = supportReturnMoneyShopService.selectAll().stream().map(SupportReturnMoneyShop::getOrgUnitId).collect(Collectors.toSet());
        List<RoomVo> rooms = movieServiceInvoker.shopRooms(supportReturnMoneyShops);
        Set<Long> roomIds = rooms.stream().map(RoomVo::getId).collect(Collectors.toSet());
        RETURN_MONEY_ROOM_EMPTY.assertNotEmpty(roomIds);

        List<FinancialAccount> accounts = financialAccountService.takeForPreview(previewLuckyMoney.getExcludes(), roomIds);
        accounts.forEach(account->{
            try{
                int plays = totalPlays(start, end, account.getRoomId(),unsupportedMovieIds);
                int cost = totalCost(start, end,account.getRoomId(),unsupportedMovieIds);
                cost /= 2;
                PreviewLuckMoneyItem item = new PreviewLuckMoneyItem();
                item.setPlayCount(plays);
                item.setAmount(cost);
                item.setRoomId(account.getRoomId());
                item.setEnd(invalid);
                item.setInitAmount(cost);
                item.setStart(begin);
                item.setType(1);
                RoomVo room = IdOperators.find(rooms, account.getRoomId());
                if(room != null){
                    item.setRoomName(room.getName());
                    item.setOrgUnitId(room.getOrgUnitId());
                    item.setOrgUnitName(room.getOrgUnitName());
                }
                previewLuckyMoney.getRecords().add(item);
            }catch (Exception e){
                logger.error("处理账号[id:{}]异常", account.getId(),e);
                previewLuckyMoney.getExcludes().add(account.getId());
            }
        });
        return previewLuckyMoney;
    }

    @Override
    public Integer count(Long movieId, String version) {
        if(movieId == null){
            return 0;
        }
        return mapper.count(movieId,version);
    }

    @Override
    public Integer remainingTime(@NotNull Token token, @Nullable Long id) {
        PROPERTY_CHECK_ERROR.assertTrue(playRecordAutoEndProperties.getEnabled(),"配置","自动结束未启用");
        PlayRecord entity = select(id);
        if(!token.hasAuthority(RoleEnum.Admin)){
            ErrorCode.ORG_UNIT_ACCESS_DENIED.assertEqual(token.getOrgUnitId(),entity.getOrgUnitId(),entity.getOrgUnitId());
        }
        MovieVo movieVo = movieServiceInvoker.movieInfo(entity.getMovieId(), entity.getMovieVersion());
        MOVIE_NOT_EXIST.assertNotNull(movieVo,()->new Object[]{
                entity.getMovieId()+"-" + entity.getMovieVersion()
        });
        float du = movieVo.getDuration()!=null?movieVo.getDuration():0;
        float seconds = du*3600f + playRecordAutoEndProperties.getMoreHours()*3600f;
        long s = (new Date().getTime() - entity.getStartTime().getTime())/1000;
        int r = (int)(seconds-s);
        return Math.max(r, 0);
    }

    @Override
    public PlayRecordAutoEndCfg cfg() {
        PlayRecordAutoEndCfg cfg = new PlayRecordAutoEndCfg();
        BeanUtils.copyProperties(playRecordAutoEndProperties,cfg);
        return cfg;
    }
}
